/*
 * DirichletFit.h
 *
 *  Created on: Apr 5, 2011
 *      Author: clint
 */

#ifndef DIRICHLETFIT_H_
#define DIRICHLETFIT_H_

#include <assert.h>
#include <armadillo>
#include <math.h>
#include <gsl/gsl_sf.h>

using namespace std;
using namespace arma;

const double CONST_EPS = 2.2204e-016;
const double CONST_LAMBDA_MAX = 1e+6;
const double CONST_ALPHA_MIN = 1e-10;



class DirichletFit {

private:

	mat dirichlet_samples_;

	rowvec dirichlet_moment_match_row();
	vec dirichlet_moment_match_col();
	double dirichlet_log_likelihood_row(rowvec alpha_vec, rowvec ln_bar_p);
	double dirichlet_log_likelihood_col(vec alpha_vec, vec ln_bar_p);
	rowvec hessian_times_gradient_row(rowvec alpha_vec, rowvec g_vec, double lambda);
	vec hessian_times_gradient_col(vec alpha_vec, vec gradient_ll, double lambda);
	bool rowvec_less_than(rowvec a, rowvec b);
	bool vec_less_than(vec a, vec b);


public:

	DirichletFit(mat data);
	virtual ~DirichletFit();
	rowvec dirichlet_fit_newton_row(rowvec alpha_vec);
	rowvec dirichlet_fit_newton_row();
	vec dirichlet_fit_newton_col(vec alpha_vec);
	vec dirichlet_fit_newton_col();
	double trigamma(double x);
	double digamma(double x);

};

#endif /* DIRICHLETFIT_H_ */
